home *** CD-ROM | disk | FTP | other *** search
/ Amnesia 7 / Amnesia - Issue 07 (1991-11-23)(Eclipse).adf / text / print_text < prev    next >
Text File  |  1989-05-09  |  14KB  |  330 lines

  1.  
  2. Hi there, Gazzer/Eclipse here with a very simple Program that will just print
  3. some text on the current CLI screen, No more, no less. So, if you are after some
  4. more advanced source code then please look elsewhere, or at least you could 
  5. write to me and just ask, and I'll be happy to oblige, my address can be found
  6. at the end of this article, however if you are new to Assembly Language coding
  7. on the Amiga Please Read on...
  8.  
  9. I'll give the whole program first and then follow on afterwards with a simple
  10. but detailed discussion of what each part of the program does.
  11.  
  12. Incidentally, I'm not expecting you to write all of this program down on paper
  13. and then Type the whole lot into Devpac, but if you have the time... you never
  14. know you might learn something while you're typing it in!  So, this file can
  15. be found in the text\print_text file on this disk. Just cut out the program
  16. between these Labels:   'Program Starts Here....'  and  'Program Ends Now...'.
  17.  
  18.  
  19. --------------------------------- Program Starts Here.... ---------------------
  20.  
  21. ; A Simple Routine to Print text to the Current CLI Screen.
  22. ; I've used the Dos WRITE routine.
  23. ; by Gazzer/Eclipse
  24.  
  25. ; Use Devpac 2 to compile.
  26. ; Please Assemble to Disk and then run from the CLI, otherwise DEVPAC
  27. ; will open a newcli and print the text, then close it immediately, without
  28. ; you getting a chance to view the Output.   Thanks.  Gazzer.
  29.  
  30.         Opt C-             ; Turn off Case Sensitivity
  31.         
  32. Openlib  = -408            ; Offset for Exec Openlib Function
  33. Closelib = -414            ; Offset  "   "   Closelib Function
  34. ExecBase =  4              ; Exec Library Base Address
  35. Output   = -60             ; Function to Retrieve current CLI handle/ID
  36. Write    = -48             ; Dos Library Write Function Offset
  37.  
  38. Start:
  39.         Move.l ExecBase,a6      ; Pointer to ExecBase Address
  40.         Lea    dosname,a1       ; Name of Library
  41.         Moveq  #0,d0            ; Any Version
  42.         Jsr    Openlib(a6)      ; Open Dos Library
  43.         Move.l d0,dosbase       ; Store Dos Library Base Address
  44.         beq    error            ; If d0 = 0 didn't work so Goto error label
  45.  
  46.         Move.l dosbase,a6       ; Move Dos Library Base Address into A6
  47.         Jsr    Output(a6)       ; Find current CLI
  48.         Move.l d0,handle        ; And, find the it's handle
  49.  
  50.         Move.l handle,d1        ; CLI handle
  51.         Move.l #text,d2         ; Text Address
  52.         Move.l #textend-text,d3 ; Text Length
  53.         Jsr    Write(a6)        ; Output Text
  54.        
  55.         Move.l ExecBase,a6      ; Exec Structure Address
  56.         Move.l dosbase,a1       ; Dos Library Base
  57.         Jsr    Closelib(a6)     ; Close Dos Library
  58.  
  59. error:  Moveq  #0,d0            ; Don't care about Version
  60.         rts                     ; Return to the CLI
  61.  
  62. Text:   dc.b   $0C              ; Clears Screen, I Put This in for Clarity
  63.         dc.b   "This message should get printed out!   Signed: Gazzer",$0a
  64.         dc.b   "And now for the second line of the text.",$0a
  65.         dc.b   "Might as well put a third one in too!!!",$0a
  66.         dc.b   $0A              ; Linefeed, put this in for tidiness
  67.         dc.b   0                ; It's advisable to Use '0' to terminate string
  68. TextEnd
  69.         even
  70. Handle: dc.l   0
  71. dosbase dc.l   0
  72. dosname dc.b   "dos.library",0
  73.         end
  74.  
  75. ------------------------------- Program Ends Now.... ---------------------------
  76.  
  77.  
  78. First Things First
  79. ==================
  80.  
  81. 8 Bits  = 1 Byte
  82. 16 Bits = 2 Bytes = 1 Word
  83. 32 Bits = 4 Bytes = 2 Words = 1 LongWord
  84.  
  85. $ signifies a Hex Value
  86. % signifies a Binary Value
  87. No prefix signifies a Decimal value.
  88.  
  89. Registers are like little 'boxes' where you can store values up to
  90. 32 Bits, which is a Longword. So, we use Bytes, Words and Longwords when we are
  91. coding, these have different extensions:
  92.  
  93.        .b = Byte     Value
  94.        .w = Word     Value
  95.        .l = LongWord Value 
  96.  
  97. The Registers which you will hear about are Address Registers, Data Registers
  98. and the Amiga-Specific Custom Registers. Let's Look at these....
  99.  
  100. Data Registers:
  101. ---------------
  102.  
  103. Data Registers hold data, what a surprise!! There are 8 registers: D0 to D7
  104. They are used as 'scratch' areas to hold values or addresses etc.
  105.  
  106. Address Registers:
  107. ------------------
  108.  
  109. Address Registers go from A0 to A7 (with A7 being reserved for the System.)
  110. These are used to store certain Address of program Variables or Labels.
  111.  
  112.  
  113. Let's continue with a brief introduction to the Motorola 68000 Instruction set:
  114.  
  115.  
  116. The MOVE instruction
  117. --------------------
  118.  
  119.         Probably the most commonly used instruction, it does what it says.
  120.         And the form is    Move <Source> <Destination>  with notable examples
  121.         being:
  122.  
  123. Note:   Move defaults to a word move i.e. Move.w 
  124.  
  125.         Move #4,d0     which would an immediate value i.e. '4' to Data
  126.                        Register D0.
  127.  
  128.         Move value,d0   which moves the value contained at the label 'value'
  129.                         into the Data Register D0. 
  130.  
  131.         Move.l #value,d0  which would move the address of the label 'value' into
  132.                           the Data register D0.
  133.  
  134.         Moveq #0,d0     which would move a small value, anything up to and
  135.                         including  0 to 127 . This is faster than the standard
  136.                         Move, and as such should be used whenever possible and
  137.                         relevant.
  138.  
  139.         Move.w #4,a0    Same as Move #4,d0 except moveing into an address
  140.                         Register.
  141.  
  142.         Move.w #6,(a0)  Note the brackets! This moves the value '6' into
  143.                         the address location of whatever A0 points to.
  144.                         i.e. say we have a label (not another one!) as such:
  145.  
  146. label: dc.w   0
  147.  
  148.         If i did Move.w #66,(a0) this would move '66' into the Variable,
  149.         so the value of it would now be 66, i.e.
  150.  
  151. Label: dc.w   66
  152.         
  153.  
  154.         Might as well discuss labels and variable...
  155.  
  156. Say we had a label as below:
  157.  
  158. Label: dc.b 6
  159.  
  160. This would mean that the Label or variable 'Label' contains a value of 6 in Byte
  161. Format, i.e two bytes, so the binary value would be: 00000110
  162. And if we had a another variable like so
  163.  
  164. Another: dc.b 99
  165.  
  166. This value '99' would be expressed in Binary as follows: 01100011
  167. In fact the Byte range would be from 0 to 255 decimal.
  168.  
  169. And a word value contained at a lable...
  170.  
  171. Wordvalue: dc.w 20000
  172.  
  173. The Maximum Value held in a word variable can be from 0 to 65535
  174.  
  175. The last one is the Longword which can be up to 2**32 (2 to the Power of 32)
  176. in size.
  177.  
  178.  
  179. The LEA instruction
  180. -------------------
  181.  
  182. This stands for Load Effective Address. And what it does is get the address of
  183. a given labeland place in in an Address Register only.
  184.  
  185.   Lea   Label,A0
  186.  
  187. Which moves the address of a variable called Label into Address Register A0.
  188.  
  189.  
  190. The BSR instruction
  191. -------------------
  192.  
  193. This stands for Branch to Sub-routine, rather like a GOSUB in Basic, or
  194. Routine(); in C.  The Syntax  is   BSR  LABEL,
  195.  
  196. THE Bcc instructions
  197. --------------------
  198.  
  199. The Bcc Branch Condition series consist of BEQ, BGT, BLS, BGE, BLE, BRA,
  200. BNE, BLT etc. etc.    BRA stands for Branch, which is a GOTO (Aaarrgghh)
  201. i.e. it branches to the Label specified and continues on from there,
  202. the syntax is  BRA LABEL 
  203.  
  204. The JSR instruction
  205. -------------------
  206.  
  207. Similar to BSR, but used to Jump to a Sub-routine at a further distance
  208. away in memory or in the Program.  The syntax is  JSR LABEL
  209.  
  210. The RTS instruction
  211. -------------------
  212.  
  213. This Returns you from a BSR or RTS. It's like a RETURN at the end of a
  214. GOSUB in Basic, or a '}' bracket signifying the end of a routine in C.
  215.  
  216. Other instructions are be Add, Sub, Divu, Mulu, etc., which would be Add,
  217. Subtract, Divide, Multiply etc.   But there are really too many of them to
  218. mention. So, I won't.  
  219.  
  220.  
  221. Now Finally a discussion of the above program
  222. =============================================
  223.  
  224. Firstly we have to stick an   OPT C- , which is a Devpac only Operand and
  225. what is does is not to differentiate between Lower and Uppercase letters.
  226.  
  227. Next, we have some Equates, i.e  Openlib = -408, or you might see it as
  228. Openlib equ -408, this just initializes some set variables which don't
  229. change at all in the program.
  230.  
  231. Then there's the START: label, which can be anything at all, you don't even
  232. need one, but I think it's nice to let people know where you're program starts.
  233.  
  234. Then we need to Open the Dos Library, which resides in memory. We do not 
  235. actually have the Address in memory, because it can reside anywhere in memory
  236. and changes in different Kickstart Versions anyway. BUT, we do have the address
  237. of the EXEC library which is also memory resident and always open and available.
  238.  
  239. So, Move the value stored in the EXECBASE equate, i.e 4, which comes out as 
  240. address 4 in memory, which is the Base Address of the Exec Library Structure in
  241. to the A6 Address register.
  242.  
  243. Now, we are going to open the Dos Library Proper using the EXEC OpenLibrary
  244. routine, and this needs two parametes, D0 must contain the version number of
  245. the Library, i've set it to 0, coz it doesn't matter. Now we also need the 
  246. name of the Library that we want to open, and this is ALWAYS in lower case, and
  247. in this case is 'dos.library' which is stored at the Dosname Label. So, we put
  248. the address of Dosname in A1. Then we JSR to this Library function, which is
  249. (please read this bit slowly while standing on one leg) an offset from the
  250. base address, i.e the Library routines are stored Back in Memory. So, using the
  251. JSR Openlib(a6)  command, we are actually saying  JSR -408(a6).
  252. If we encounter an error, i.e. if the Routines returns a null value '0' in D0
  253. then we were not successful in opening the Library and Go to the Erro Label
  254. and Exit the Program and go back to the CLI. Otherwise we continue....
  255.  
  256. Now that we have the Dos Library Open, all is wonderful and we can continue
  257. on wearing a smile and relax, if you've got this far in the text, I must 
  258. congratulate you on staying Awake and Sane!! 
  259.  
  260. Noe, we must find out how to access the CLI Screen, we have run the Program
  261. from. We Load the DosBase address into register A6. We then use a DOS Library
  262. routine called Output(), which tells us what the current CLI 'handle' or ID is.
  263. We don't need to supply any parameters. and if all goes well (which it will) 
  264. then we have the 'handle' in d0. Then we just save this value to a variable 
  265. called Handle, for later use.
  266.  
  267. Now to the action packed bit, we actually get to write something to the Screen!
  268. We Use the DOS Write() routine, which needs some parameters, namely the CLI
  269. handle in D1, the address of the Text to Print in D2, the size of the Text
  270. that we want to print in D3. Then we Access offset -48 from the Dos Library
  271. Base address stored in Dosbase. So, we have JSR -48(a6), which actually
  272. prints the text on screen stored at the text label.
  273.  
  274. Now that we've accomplished what we want in the program we must do some tidying
  275. up and then exit back to the CLI.  We first of all Move the EXECBASE address
  276. '4' into the A6 address Register. Next we need to supply the Dos Library Base
  277. Address in A1, then we call the EXEC CloseLib() function to close the DOS 
  278. Library.
  279.  
  280. Now we exit gracefully be setting the Program Return Value stored in Register
  281. D0 to 0, by doing a nice Moveq #0,d0. and then we RTS, i.e. Return from
  282. Subroutine, which effectively ends the Program safely.
  283.  
  284. At the end of the Program, we have different Variables:
  285.  
  286. Text:   dc.b   $0C              ; Clears Screen, I Put This in for Clarity
  287.         dc.b   "This message should get printed out!   Signed: Gazzer",$0a
  288.         dc.b   "And now for the second line of the text.",$0a
  289.         dc.b   "Might as well put a third one in too!!!"
  290.         dc.b   $0A              ; Linefeed, Just put this in for tidiness
  291.         dc.b   $0A              ; Linefeed, also put this in for tidiness
  292.         dc.b   0                ; It's advisable to Use '0' to terminate.
  293. TextEnd
  294.  
  295. The first one is where we store the text we want to print on the screen.
  296. I've put $0C, which is the Hex Value of 12, which is a Code for clearing the
  297. screen. The Text is stored in Character of Byte format, hence the  dc.b " 
  298. prefix. I have also put in the Linefeed code $0a, which is 10 decimal, which
  299. just goes on to next line on the screen. You can of course leave out these
  300. codes if you only want to print one line of text. I just put them in for
  301. Neatness. Next we have the Label TextEnd which is used in the Program to
  302. work out the end of the text, so when we say Text-TextEnd, we are actually
  303. getting the Length of all of the text! Clever, Eh!!
  304. Then 'even' operand just makes our current Address Even, coz the Amiga and
  305. the 68000 Processor really hate odd addresses!
  306.  
  307.         even
  308. Handle: dc.l   0
  309. dosbase dc.l   0
  310. dosname dc.b   "dos.library",0
  311.  
  312. Next, is were we store the CLI ID number or handle, and we use a longword
  313. to store this as it comes in that form. The Same with the DosBase Address
  314. Variable which is also a LongWord, so that we can store a 32 Bit address.
  315. Next, is the name of the Dos Library, which needs to be in lower case.
  316.  
  317. Finally, we put the END operand at the end of the program, this is not
  318. absolutely necessary, but is a good idea all the same.
  319.  
  320. Well, that's my lot for this month, hope someone finds this article useful
  321. and if you have any comments/feedback then please feel free to Write to me
  322. at the following address.
  323.  
  324.                 Gazzer/Eclipse
  325.                 3, O' Curry Rd
  326.                   Sth Cir Road
  327.                       Dublin 8
  328.                        Ireland                  
  329.                                                   See ya, Gazzer.
  330.